﻿#region Copyright (c) 2010 R. Uittenbosch
/*
* Copyright (C) 2010 R. Uittenbosch
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 
* associated documentation files (the "Software"), to deal in the Software without restriction, including 
* without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
* copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the 
* following conditions:
* 
* The above copyright notice and this permission notice shall be included in all copies or substantial 
* portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO 
* EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#endregion

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32;
using LinkedService.Mobile;

namespace LinkedIn.Mobile
{

  /// <summary>
  /// Configuration  class for generic settings
  /// </summary>
  public class Configuration : IConfiguration
  {
    #region RegistryHandling
    private string _RegistryKeyName = @"Software\LinkedIn for Windows Mobile";

    /// <summary>
    /// Get an configuration entry
    /// </summary>
    /// <param name="tag"></param>
    /// <returns></returns>
    private string GetValueFromRegistry(string tag)
    {
      string val = string.Empty ;
      try
      {
        // Try to get the value from the registry
        RegistryKey internetKey = Registry.CurrentUser.OpenSubKey(_RegistryKeyName);
        if (internetKey != null)
          val = (string)internetKey.GetValue(tag);
      }
      catch
      {
        // Exception -> no permission
      }
      return val;
    }

    /// <summary>
    /// Set a configuration item
    /// </summary>
    /// <param name="tag"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    private object SetValueInRegistry(string tag, object value)
    {
      try
      {
        // Try to set the value to the registry
        RegistryKey internetKey = Registry.CurrentUser.CreateSubKey(_RegistryKeyName);
        if (internetKey != null)
        {
          internetKey.SetValue(tag, value);
          internetKey.Close();
        }
      }
      catch { }
      if (value == null)
        return string.Empty;
      return value;
    }
    #endregion

    #region Constructor
    /// <summary>
    /// Constructor
    /// </summary>
    public Configuration()
    {
      _cache = new Dictionary<string, object>();
      // Init the dumppath, default, current directory.
      SetItem("DumpPath",@".\Application Data\LinkedIn for Windows Mobile");     
      LoadCache();
    }

    #endregion

    #region Caching
    private Dictionary<string, object> _cache;

    /// <summary>
    /// Load the cache from the registry
    /// </summary>
    private void LoadCache()
    {
      RegistryKey internetKey = Registry.CurrentUser.CreateSubKey(_RegistryKeyName);
      if (internetKey != null)
      {
        // Get all names below the basename
        string[] names = internetKey.GetValueNames();
        foreach (string name in names)
        {
          object obj = internetKey.GetValue(name);         
          int val = 0;
          // Check for a number
          if (obj.ToString().TryParse(out val))
            _cache[name] = val;
          // Check for boolean objects.
          else if (obj.ToString().CompareTo("True") == 0 || obj.ToString().CompareTo("False") == 0)
            _cache[name] = "True".CompareTo(obj.ToString()) == 0;
          // Anything else
          else
            _cache[name] = obj;
        }
      }
    }
    #endregion
    
    #region IConfiguration Members
    public string[] ContainedItems 
    {
      get
      {
        // Return all keys
        return _cache.Keys.ToArray();
      }
    }

    public T GetItem<T>(string name, T def)
    {
      // If it does not yet exists, add the default value for it.
      if (!_cache.ContainsKey(name))
        SetItem<T>(name, def);

      return (T)_cache[name];
    }

    public T GetItem<T>(string name)
    {
      return GetItem(name, default(T));      
    }


    /// <summary>
    /// Set a configuration item to the cache.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="name"></param>
    /// <param name="item"></param>
    public void SetItem<T>(string name, T item)
    {
      // Set the value in the registry and add it to the cache
      _cache[name] = SetValueInRegistry(name, item);
    }

    #endregion
  }
}
